<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
ul,dl{margin:0;padding:0;}
li{list-style-type:none;}
#banner{width:640px;height:320px;margin:0 auto;position:relative;overflow:hidden;}
#lunbo{}
#lunbo li{position:absolute;top:0;left:640px;}
#lunbo li.curr{left:0;}
#lunbo img{display:block;}
#banner>span{display:block;width:30px;height:80px;text-align:center;line-height:80px;position:absolute;top:50%;margin-top:-40px;color:#FFF;background:rgba(0,0,0,0.6);z-index:1;user-select:none;cursor:pointer;}
#leftBtn{left:0;}
#rightBtn{right:0;}
#tabs{position:absolute;width:100%;height:40px;left:0;bottom:10px;text-align:center;z-index:1;}
#tabs dd{display:inline-block;width:20px;height:20px;margin:0 5px;background:rgba(0,0,0,0.4);}
#tabs dd.curr{height:40px;opacity:1;}
</style>
</head>
<body>
<div id="banner">
	<span id="leftBtn"><</span>
	<span id="rightBtn">></span>
	<dl id="tabs"></dl>
	<ul id="lunbo"></ul>
</div>
<script>
/*--------------1、动态生成图片列表-----------------
定义全局变量，lunbo、oli
*/
//1-----oli:图片列表里li的集合
var lunbo=$("#lunbo")[0],oli,

//2-----width:显示区域的宽度，t,setTimeout的id
banner=$("#banner")[0],
width=banner.offsetWidth,
t,
//3-----endAnimation:动画是否播放完毕，状态，true or false
leftBtn=$("#leftBtn")[0],
rightBtn=$("#rightBtn")[0],
endAnimation=true,
//4-----odd:选项卡的集合
tabs=$("#tabs")[0],odd;


function $(s){
	return document.querySelectorAll(s);
}
var arr=[//数组，[{src:"图片路径",link:"链接地址"}]
	{src:"../images/1.jpg",link:"a.html"},
	{src:"../images/2.jpg",link:"b.html"},
	{src:"../images/3.jpg",link:"c.html"},
	{src:"../images/4.jpg",link:"d.html"}
]
function init(arr){
	/*
	reduce():
	数组方法，求和
	参数1--function(a,b){return a+b;} 
			我觉得就是a+=b
			---a:每次求和后的结果，b:数组每一项
	参数2--初始值，如果是数字，默认是0，如果是字符串，默认是""
	*/
	lunbo.innerHTML=arr.reduce(function(a,b){
		/*第四步，动态生成选项卡列表*/
		tabs.innerHTML+="<dd></dd>";
		//拼接图片列表中的li
		return a+'<li><a href="'+b.link+'"><img src="'+b.src+'"></a></li>';
	},"");
	oli=$("#lunbo li");
	//初始化时，显示第一个li（left:0）
	oli[0].className="curr";

	odd=$("#tabs dd");
	//设置第一个选项，class为curr,与图片显示的索引对应
	odd[0].className="curr";
	t=setTimeout(function(){//3秒后播放
		run(arr.length);
	},2000);
}
init(arr);//初始化时，调用函数
/*--------------2、自动播放-----------------
setTimeout(function(){},毫秒)--每隔一段时间播放一次
setInterval(function(){},毫秒)--每隔一段时间图片移动一次，直到移动完整张图片时停止

--变量：curr-当前显示的图片
       index-当前显示图片的索引,获取方法：自定义getDomIndex函数
       nextIndex-下一个图片的索引：当前图片是最后一张，值是0，
       			否则值是index+1
       next-下一个图片  oli[nextIndex]
用计时器设置动画：500毫秒，每5毫秒移动一次
--变量：distance:图片移动距离，值是当前显示图片的偏移距离curr.offsetLeft
distance递减,递减量设置的是 width/100
判断图片是否已经移出显示区域，
       如果已经移出，设置distance=-width
       清除计时器，clearInterval()
       去除当前图片的class，将curr名字，给next
       隔2秒再次运行播放函数,setTimeout(function(){
			run()
       },2000) 
当前curr图片的left值=distance值
next的left值=width+distance值
function run(n){
	var curr=$("#lunbo li.curr")[0],next,nextIndex,
	index=getDomIndex(oli,curr);
	clearTimeout(t);
	next=oli[nextIndex];
	var timer=setInterval(function(){
		var distance=curr.offsetLeft;
		distance-=width/50
		if(distance<=-width){
			distance=-width;
			clearInterval(timer);
			clearTimeout(t);
			curr.className="";
			next.className="curr";
			t=setTimeout("run("+n+")",2000);//循环播放，每隔3秒播放一次
		}
		curr.style.left=distance+"px";
		next.style.left=width+distance+"px";
	},10)
}
*/
/*--------------3、点击左右按钮-----------------
点击时，检测一下动画是否在播放，如果是播放完成的状态，才可以执行
--全局变量：endAnimation初始值是true，运行时是false，动画完成时是true
if(endAnimation){
	run()
}
1、右边按钮：下一张
function run(n){
	var curr=$("#lunbo li.curr")[0],next,nextIndex,
	index=getDomIndex(oli,curr);
	clearTimeout(t);
	next=oli[nextIndex];
	endAnimation=false;
	var timer=setInterval(function(){
		var distance=curr.offsetLeft;
		distance-=width/50
		if(distance<=-width){
			distance=-width;
			clearInterval(timer);
			clearTimeout(t);
			endAnimation=true;
			curr.className="";
			next.className="curr";
			t=setTimeout("run("+n+")",2000);//循环播放，每隔3秒播放一次
		}
		curr.style.left=distance+"px";
		next.style.left=width+distance+"px";
	},10)
}
2、左边按钮：上一张
--动画默认是向左移动，改成向右移动，点击时需要一个参数，true或false
----m:控制方向，-1的时候，向左移动，1的时候向右移
run里进行判断，
如果是左按钮点击的，设置下一个图的索引
	----如果当前是第一张图，下一个图是最后一张，否则就是index-1
	m取1
如果不是左按钮点击（包含自动播放，右按钮等）
	下一个图的索引与自动播放时一样，m取-1

function run(n){
	var curr=$("#lunbo li.curr")[0],next,nextIndex,m,
	index=getDomIndex(oli,curr);
	clearTimeout(t);
	if(isLeft){
		nextIndex=index==0?n-1:index-1;
		m=1
	}else{
		nextIndex=index==n-1?0:index+1;
		m=-1
	}
	next=oli[nextIndex];
	endAnimation=false;
	var timer=setInterval(function(){
		var distance=curr.offsetLeft;
		distance+=m*width/50
		if(Math.abs(distance)>=width){
		//检测移动距离，是否图片完全移出显示区
			distance=m*width;
			clearInterval(timer);
			clearTimeout(t);
			endAnimation=true;
			curr.className="";
			next.className="curr";
			t=setTimeout("run("+n+")",2000);//循环播放，每隔3秒播放一次
		}
		curr.style.left=distance+"px";
		next.style.left=-m*width+distance+"px";
	},10)
}
*/
/*--------------4、tab选项卡-----------------
图片上显示与图片对应的选项（数量对应，索引对应）
动态创建dl，dd个数就是数组长度
run(图片数量,是否左按钮点击,点击的dd索引)
--第三个参数，就是run里面的nextIndex
---run里判断一下是否点击了选项卡
-----是：检测方向，nextIndex<index  m取1，否则m取-1
setInterval里，给对应的选项卡加className curr
*/
function run(n,isLeft,tabIndex){
	//当前显示的图片
	var curr=$("#lunbo li.curr")[0],
	//在oli里查找curr的位置
	index=getDomIndex(oli,curr),next,nextIndex,m;
	endAnimation=false;
	clearTimeout(t);
	if(isLeft){//点击左按钮执行
		nextIndex=index==0?n-1:index-1;
		m=1
	}else{
		nextIndex=index==n-1?0:index+1;
		m=-1
	}
	if(typeof tabIndex!="undefined"){
	//判断是否有tabIndex参数  tabIndex=0
		m=tabIndex>index?-1:1;
		nextIndex=tabIndex;
	}
	next=oli[nextIndex];
	var timer=setInterval(function(){
		//动画,需要移动距离
		//淡入淡出的通过opacity
		var distance=curr.offsetLeft;//移动距离
		//distance-=width/50   a-=5  a=a-5      a=a+(-5)
		distance+=m*width/50;//每10毫秒移动的距离  a=a+5   1  *-1
		//if(distance<=-width){
		if(Math.abs(distance)>=width){//判断移动距离是否超过宽度
			//distance=-width;                  a=-5
			distance=m*width;//最远的移动距离      a=5
			clearInterval(timer);
			clearTimeout(t);
			curr.className="";
			next.className="curr";
			odd[index].className="";
			odd[nextIndex].className="curr";
			endAnimation=true;//控制点击的变量，只有在图片显示完才能点击执行
			t=setTimeout("run("+n+")",2000);//循环播放，每隔3秒播放一次
		}
		//向右移动，distance是正值
		curr.style.left=distance+"px";
		//next.style.left=width+distance+"px";  a=5
		next.style.left=-m*width+distance+"px";// a=-5
	},10)
}

tabs.onclick=function(e){
	if(e.target.tagName=="DD"&&endAnimation&&e.target.className.indexOf("curr")==-1){
		//判断：点击的是dd，dd的class不含curr，动画未播放
		var dindex=getDomIndex(odd,e.target);
		//dindex 下一次要播放的图片的索引（下一个当前的dd）
		run(arr.length,false,dindex);
	}
}
function getDomIndex(oli,target){
	/*类似indexOf的操作,两个参数:
	1:要在哪找
	2:找什么
	找到时，返回位置，找不到返回-1
	*/
	for(var i=0;i<oli.length;i++){
		if(oli[i]==target){//返回和target一致的元素的索引
			return i;
		}
	}
	return -1;
}



rightBtn.onclick=function(){
	if(endAnimation){//检测是否播放完毕
		run(arr.length);
	}
}
leftBtn.onclick=function(){
	if(endAnimation){
		run(arr.length,true);
	}
}
/*
setTimeout(function(){
	setInterval(function(){//每隔2秒运行一次
		图片移动
		当图片移动到最大值，停止计时器
		    准备重新获取当前显示的图片，通过class=curr

	},10)
},2000)


*/
banner.onmouseenter=function(){
	clearTimeout(t);
}
banner.onmouseleave=function(){
	clearTimeout(t);
	t=setTimeout(function(){//3秒后播放
		run(arr.length);
	},2000);
}
/*
动态添加列表：
--for循环中动态生成li标签，appendChild
--var str="";
		for(){
			str+="<li></li>"
		}
		ul.innerHTML=str
--arr.reduce(function(a,b){
	return a+b;

})
*/
/*
轮播图需求：
1、动态生成轮播图列表  OK
--创建数组
--将数组的元素变成列表的每一项
2、每隔？时间播放一次
--setTimeout  时间间隔
--setInterval  动画
--找到当前显示的图片，下一张图片
----当前显示：根据class=curr获取
----下一张：当前显示的图片的索引，索引+1，如果显示的是最后一张，下一张就是第一张
3、鼠标放在图片上，停止播放，移开，开始播放
4、点击左右按钮，控制播放方式
*/
</script>	
</body>
</html>